<?php
/**
 * WQPHP封装工具类，仅供学习研究使用，禁止任何形式的转载发布
 * User: Jessica@aweb.wang
 * Date: 2023/3/10 14:50
 * Email: <1194323013@qq.com>
 *                            _ooOoo_
 *                           o8888888o
 *                           88" . "88
 *                           (| -_- |)
 *                           O\  =  /O
 *                        ____/`---'\____
 *                      .'  \\|     |//  `.
 *                     /  \\|||  :  |||//  \
 *                    /  _||||| -:- |||||-  \
 *                    |   | \\\  -  /// |   |
 *                    | \_|  ''\---/''  |   |
 *                    \  .-\__  `-`  ___/-. /
 *                  ___`. .'  /--.--\  `. . __
 *               ."" '<  `.___\_<|>_/___.'  >'"".
 *              | | :  `- \`.;`\ _ /`;.`/ - ` : | |
 *              \  \ `-.   \_ __\ /__ _/   .-` /  /
 *         ======`-.____`-.___\_____/___.-`____.-'======
 *                            `=---='
 *        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 *                      Buddha Bless, No Bug !
 **/

namespace app\common\utils;
class TokenUtils
{
    private $signKey = 'p9Uui666666666yyyxxrffghhjkkh';

    private $header = [
        'typ' => 'JWT',
        'alg' => 'SHA256',
    ];

    private $payload = [];

    function __construct()
    {
        $expiresAt = strtotime('+10hour');
        $this->withExpiresAt($expiresAt);
    }

    public function withPayload($payload)
    {
        $this->payload = $payload;
        return $this;
    }

    public function withClaim($key, $value)
    {
        $this->payload[$key] = $value;
        return $this;
    }

    public function withExpiresAt($expiresAt)
    {
        $this->withClaim('exp', $expiresAt);
        return $this;
    }

    public function withIdentity($identity)
    {
        $this->withClaim('jti', $identity);
        return $this;
    }

    public function getClaim($key)
    {
        return $this->payload[$key] ?? null;
    }

    private function signature($data, $signKey, $alg)
    {
        return hash_hmac($alg, $data, $signKey, true);
    }

    public function createToken()
    {
        $base64header = base64_encode(json_encode($this->header));
        $base64payload = base64_encode(json_encode($this->payload));
        $data = $base64header . '.' . $base64payload;
        $signature = $this->signature($data, $this->signKey, $this->header['alg']);
        $base64signature = base64_encode($signature);
        $token = $data . '.' . $base64signature;
        return $token;
    }


    public function getDecodePayload($token)
    {
        $result = null;
        try {
            list($base64header, $base64payload, $signature) = explode('.', $token);
            $data = $base64header . '.' . $base64payload;

            $newSignature = $this->signature($data, $this->signKey, $this->header['alg']);
            $newSignature = base64_encode($newSignature);


            if ($newSignature == stripslashes($signature)) {
                $payload = base64_decode($base64payload);
                $result = json_decode($payload, true);
            }
        } catch (\Exception $e) {

        }
        return $result;
    }

    public function verifyToken($token)
    {
        $result = false;
        $arr = $this->getDecodePayload($token);
        if (isset($arr['exp']) && $arr['exp'] > time()) {
            $result = true;
        }
        return $result;
    }
}